#ifndef LIBUSB_DRIVER_H_INC
#define LIBUSB_DRIVER_H_INC

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "..\vcard_def.h"
#include "..\firm_def.h"
#include "..\..\..\collection\ptr_list.h"
#include "libusb.h"

class RecvItem : public ListItem {
public:
	BYTE* m_frameBuffer;
	DWORD m_length;
public:
	RecvItem(BYTE* buffer, DWORD len);
	virtual ~RecvItem();

	virtual const char* Name(void) { return(""); }
};

class LibusbDriver {
public:
	static const int RCV_SIZE = 1280;
	static const int SND_SIZE = 64;
private:
	static BOOL	M_initOk;
	//static libusb_context* M_ctx;
	static LibusbDriver* M_libusbDrivers[MAX_CARD_NUM];
	static int	M_nDevices;
	static BOOL _InitLibusbOnce();

public:
	static int CountDevices(void);
	static int Create(void);
	static void Release(void);
	static LibusbDriver* GetDriver(int i);

protected:
	WORD		m_firmModel;
	libusb_device_handle* m_h;
	BOOL		m_openError;
	int			m_commError;
	int			m_reconnectState;
	DWORD		m_stateDelayCount;
	LibusbDriver* m_reconnectedDriver;

	DWORD		m_recvSubmitCount;
	CxObjQueue*	m_recvFrameQuque;
	DWORD		m_sendErrorCount;
	DWORD		m_recvErrorCount;

public:
	LibusbDriver(libusb_device* dev);
	virtual ~LibusbDriver();

	virtual int GetFirmModel(void) { return(m_firmModel); }
	virtual int GetCommError(void);
	virtual void AutoReconnectOnTick(DWORD ms);
	virtual void  _SubmitRecvTransfer(DWORD n, DWORD msout);
	virtual DWORD Send(BYTE* txBuf, DWORD toSendLen, BOOL prepareReply, DWORD msout);
	virtual void  OnSendCallback(libusb_transfer* transfer);
	virtual DWORD Receive(BYTE* rxBuf, DWORD bufSize, DWORD msout);
	virtual void  OnReceiveCallback(libusb_transfer* transfer);
};

#endif
